﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Contact.DAL.Models.User;
using Contact.DAL.Models.Worktime;
using ContactMvc4TB.Helpers.HelperClasses;
using ContactMvc4TB.Models.Worktime.Helpers;
using EFDataModel;
using GlobalResources;
using TimeManagement;

namespace ContactMvc4TB.Models.Worktime
{
    /// <summary>
    /// Anlegen eines Arbeitszeit Eintrags
    /// </summary>
    public class CreateWorktimeEntryModel
    {
        #region Helper Properties
        /// <summary>
        /// Der Aktuelle CurrentController um hier auch Messages ausgeben zu können.
        /// </summary>
        private Controller Controller { get; set; }

        /// <summary>
        /// Die Arbeitszeiteinstellungen
        /// </summary>
        public EFWorktimeSetting WorktimeSettings { get; set; }

        /// <summary>
        /// Berechnet einfach aus der Startzeit die passenden Minuten
        /// </summary>
        public double StartTimeInMinutes
        {
            get
            {
                TimeSpan span = new TimeSpan(0, StartTime.Hour, StartTime.Minute, 0);
                return span.TotalMinutes;
            }
        }

        /// <summary>
        /// Berechnet einfach aus der Endzeit die passenden Minuten
        /// </summary>
        public double EndTimeInMinutes
        {
            get
            {
                TimeSpan span = new TimeSpan(0, EndTime.Hour, EndTime.Minute, 0);
                return span.TotalMinutes;
            }
        }

        /// <summary>
        /// Damit die Dropdownliste funktioniert muss das Property "WorktimeType" ein String sein in dem der Int für den passenden Eintrag steht.
        /// </summary>
        public EWorktimeType EWorktimeType
        {
            get { return (EWorktimeType)int.Parse(WorktimeType); }
        }
        #endregion

        #region Modeldata

        /// <summary>
        /// Alle Buttons auf der Seite haben den Namen "SubmitType" und je nachdem welcher Button den Postback ausgelöst hat
        /// steht hier der jeweilige String drin.
        /// </summary>
        public string SubmitType { get; set; }

        /// <summary>
        /// Die aktuelle UserId für die die Arbeitszeit eingetragen werden soll.
        /// </summary>
        public long UserId { get; private set; }

        /// <summary>
        /// ArbeitszeitId Eintrag, die Id für die der Arbeitszeiteintrag geladen bzw. angezeigt wird.
        /// bei 0 handelt es sich um einen neuen Eintrag.
        /// </summary>
        public long WorktimeId { get; set; }

        /// <summary>
        /// Der Tag für den aktuellen Arbeitszeiteintrag
        /// </summary>
        [Display(Name = "CurrentDate", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Date)]
        public DateTime CurrentDate { get; set; }

        /// <summary>
        /// Startzeitpunkt für den Arbeitszeiteintrag
        /// </summary>
        [Display(Name = "Starttime", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Time)]
        public DateTime StartTime { get; set; }

        /// <summary>
        /// Endzeitpunkt für den Arbeitszeiteintrag
        /// </summary>
        [Display(Name = "Endtime", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Time)]
        public DateTime EndTime { get; set; }

        /// <summary>
        /// Der Ausgewählte Zeitstring aus dem Slidecontrol
        /// </summary>
        public string SelectedTimeString { get; set; }

        /// <summary>
        /// Bezeichnung für den Arbeitszeiteintrag
        /// </summary>
        [Display(Name = "Description", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Text)]
        [StringLength(200)]
        public string Description { get; set; }

        /// <summary>
        /// Beschreibung/Notiz für den Arbeitszeiteintrag
        /// </summary>
        [Display(Name = "Notice", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Text)]
        [StringLength(2000)]
        public string Notice { get; set; }

        /// <summary>
        /// Überstunden Ausgleich eintragen, geht nur beim Typ Worktime, bei allen anderen wird das Feld ausgeblendet.
        /// </summary>
        [Display(Name = "OvertimeAdjustment", ResourceType = typeof(WorktimeViews))]
        [DataType(DataType.Currency)]
        public int OvertimeInMinutes { get; set; }

        /// <summary>
        /// Alle wichtigen Statistikdaten für den aktuellen View.
        /// </summary>
        public StatisticWorktimeData StatisticWorktimeData { get; set; }

        /// <summary>
        /// Es handelt sich um einen Manuellen Überzeiteneintrag, hier werden alle restlichen Felder auf der Oberfläche "deaktiviert"
        /// </summary>
        public bool IsManualOvertime { get; set; }

        /// <summary>
        /// Der Typ des Arbeitszeiteintrags
        /// </summary>
        public string WorktimeType { get; set; }

        /// <summary>
        /// Der das ausgewählte Projekt.
        /// </summary>
        public long? SelectedProject { get; set; }

        /// <summary>
        /// Liste der Projekte des aktuellen Users
        /// </summary>
        [Display(Name = "Projektliste", ResourceType = typeof(WorktimeViews))]
        public IEnumerable<SelectListItem> ProjectList
        {
            get
            {
                List<SelectListItem> items = new List<SelectListItem>();
                //Alle aktiven Projekte des Users ermitteln und unserer Liste hinzufügen
                WorktimeSettingsRepository settings = new WorktimeSettingsRepository(CurrentHttpContext.GetDataModel());
                foreach (EFWorktimeProject project in settings.LoadActiveProjects(UserId))
                {
                    items.Add(new SelectListItem { Value = project.Id.ToString(), Text = project.Name });
                }

                return new SelectList(items, "Value", "Text");
            }
        }

        /// <summary>
        /// WorktimeType, bei Listen wird nur der Getter gesetzt, für den Value selbst gibt es noch ein extra Property
        /// </summary>
        [Display(Name = "Arbeitszeittyp", ResourceType = typeof(WorktimeViews))]
        public IEnumerable<SelectListItem> WorktimeTypeList
        {
            get
            {
                List<SelectListItem> items = new List<SelectListItem>();
                items.Add(new SelectListItem { Value = ((int)EWorktimeType.Worktime).ToString(), Text = WorktimeHelper.GetWorktimeTypeString(EWorktimeType.Worktime) });
                items.Add(new SelectListItem { Value = ((int)EWorktimeType.Breaktime).ToString(), Text = WorktimeHelper.GetWorktimeTypeString(EWorktimeType.Breaktime) });
                items.Add(new SelectListItem { Value = ((int)EWorktimeType.Holiday).ToString(), Text = WorktimeHelper.GetWorktimeTypeString(EWorktimeType.Holiday) });
                items.Add(new SelectListItem { Value = ((int)EWorktimeType.Illness).ToString(), Text = WorktimeHelper.GetWorktimeTypeString(EWorktimeType.Illness) });
                items.Add(new SelectListItem { Value = ((int)EWorktimeType.Projecttime).ToString(), Text = WorktimeHelper.GetWorktimeTypeString(EWorktimeType.Projecttime) });
                items.Add(new SelectListItem { Value = ((int)EWorktimeType.Qualification).ToString(), Text = WorktimeHelper.GetWorktimeTypeString(EWorktimeType.Qualification) });
                items.Add(new SelectListItem { Value = ((int)EWorktimeType.OfficalHoliday).ToString(), Text = WorktimeHelper.GetWorktimeTypeString(EWorktimeType.OfficalHoliday) });
                return new SelectList(items, "Value", "Text");
            }
        }

        /// <summary>
        /// Der Typ der Arbeitseintragsliste der angezeigt werden soll, ob die Liste die Tageseinträge anzeigen soll oder die letzten xx Einträge
        /// </summary>
        public EWorktimeListTypes WorktimeListType { get; set; }

        /// <summary>
        /// Liste mit den bisherigen Arbeitszeiteintragungen
        /// </summary>
        public List<ListEntry> WorktimeList { get; set; }

        /// <summary>
        /// Liste mit den Tagesarbeitszeiteintragungen für das Diagramm
        /// </summary>
        public List<ListEntry> WorktimeListDiagramm { get; set; }
        #endregion

        #region Konstruktor
        /// <summary>
        /// 
        /// </summary>
        /// <param name="controller">Der Aktuelle CurrentController um z.b. Messages anzuzeigen.</param>
        /// <param name="userId">Die UserId für die die Daten geladen und angezeigt werden sollen </param>
        public CreateWorktimeEntryModel(Controller controller, long userId)
        {
            InitializeModel(controller, userId);
        }

        /// <summary>
        /// Standardkonstruktor, wird z.b. beim laden des Models benötigt.
        /// </summary>
        public CreateWorktimeEntryModel()
        {

        }

        /// <summary>
        /// Initialisiert die wichtigsten Modeldaten und muss immer aufgerufen werden. Wird standardmäßig von einem Konstruktor aufgerufen mit Parametern.
        /// </summary>
        /// <param name="controller">Der Aktuelle CurrentController um z.b. Messages anzuzeigen.</param>
        /// <param name="userId">Die UserId für die die Daten geladen und angezeigt werden sollen </param>
        public void InitializeModel(Controller controller, long userId)
        {
            Controller = controller;
            UserId = userId;

            //Die Worktimeeinstellungen für den User laden, diese werden immer benötigt.
            WorktimeSettingsRepository settingsRepository = new WorktimeSettingsRepository(CurrentHttpContext.GetDataModel());
            WorktimeSettings = settingsRepository.LoadWorktimeSetting(userId);

            //Prüfen ob bereits WorktimeSettings für den aktuellen User und den der bearbeitet werden soll anglegt wurde, wenn nicht Defaultsettings anlegen
            if (CurrentSession.GetCurrentUser().EFWorktimeSetting == null && WorktimeSettings == null)
            {
                try
                {
                    EditWorktimeSettingsModel model = new EditWorktimeSettingsModel(controller);
                    model.LoadModelData(userId);
                    model.SaveModelData(userId, controller);
                    //Die Settings erneut laden.
                    WorktimeSettings = settingsRepository.LoadWorktimeSetting(userId);
                }
                catch (Exception exception)
                {
                    EFDebugging.Debugging.WriteLog(string.Format("Fehler beim Anlegen eines Defaultsettings für die UserId '{0}'", userId), exception);
                }
            }
        }
        #endregion

        #region Public Functions
        /// <summary>
        /// Laden der Modeldaten für das übergebene Datum. - Hier wird ein Leerer Eintrag mit dem übergebenen Datum geladen.
        /// </summary>
        /// <param name="date">Das Datum für das die Einträge geladen werden sollen.</param>
        public void LoadModelData(DateTime? date)
        {
            date = date ?? DateTime.Now.Date;
            InitializeModelData(date.Value);
            LoadDefaultData();
        }

        /// <summary>
        /// Laden der Modeldaten für die Übergebene worktimeId.
        /// </summary>
        /// <param name="worktimeId">Für diese worktimeId die passende Worktime aus der DB ins Model laden.</param>
        public void LoadModelData(long worktimeId)
        {
            //Wenn der Eintrag initialisiert werden soll, dann die Standardaten laden
            if (worktimeId == 0)
            {
                //Wird nur aufgerufen wenn die Seite neu angezeigt wird und noch keine weitere Auswahl stattgefunden hat.
                InitializeModelData(DateTime.Now.Date);
            }
            else
            {
                //Laden des übergebenen Arbeitszeiteintrags
                WorktimeRepository worktimeRepository = new WorktimeRepository(CurrentHttpContext.GetDataModel());
                EFWorktimeEntry worktimeEntry = worktimeRepository.GetWorktimeEntry(UserId, worktimeId);
                //Prüfen ob der Eintrag geladen werden konnte.
                if (worktimeEntry != null)
                {
                    //Initialisieren der Modeldaten.
                    WorktimeId = worktimeEntry.ID;
                    CurrentDate = worktimeEntry.EFWorktime.EntryDate;
                    StartTime = worktimeEntry.StartTime;
                    EndTime = worktimeEntry.EndTime;
                    Description = worktimeEntry.Description;
                    Notice = worktimeEntry.Notice;
                    SelectedProject = worktimeEntry.EFWorktimeProjectId ?? -1;

                    //Prüfen ob es sich um einen "eigenen" Überstundeneintrag handelt, nur diese können direkt bearbeitet werden.
                    IsManualOvertime = worktimeEntry.EFWorktime.ManualOvertime != 0;
                    if (IsManualOvertime)
                    {
                        OvertimeInMinutes = worktimeEntry.EFWorktime.ManualOvertime;
                    }

                    WorktimeType = ((int)worktimeEntry.WorkingtimeType).ToString();
                    //Das Setting wird in der DB gespeichert kann aber nicht direkt in den Settings angegeben werden, da wir uns das automatisch merken, sobad das Property auf der Oberfläche angepasst wird.
                    WorktimeListType = CurrentSession.GetCurrentUser().EFWorktimeSetting.WorktimeListType;
                }
                else
                {
                    CustomMessage.CurrentMessage(Controller).AddMessage(SystemMessages.LoadWorktimeError, MessageTypes.error);
                }
            }

            LoadDefaultData();
        }

        /// <summary>
        /// Laden von Standarddaten beim Speichern und Laden.
        /// </summary>
        public void LoadDefaultData()
        {
            //Die Liste mit den Arbeitszeiteinträgen muss immer geladen werden
            InitializeWorktimeList();

            //die Statistikdaten laden für das übergebenen Datum und dem passenden User
            StatisticWorktimeData = new StatisticWorktimeData(UserId);
            StatisticWorktimeData.LoadStatisticData(CurrentDate);
        }

        /// <summary>
        /// Da auf der Oberfläche je nach geklicktem Button eine unterschiedliche Aktionen ausgeführt werden soll
        /// wird hier unterschieden was genaus ausgeführt werden soll.
        /// </summary>
        /// <param name="worktimeId">Die ArbeitszeitId für die der Eintrag geladen werden soll, wenn erforderlich</param>
        public void ExcecuteBySubmitType(long worktimeId)
        {
            //Anlegen eines neuen Arbeitszeit Eintrags
            if (SubmitType == WorktimeHelper.BtnCreateWorktimeEntry)
            {
                SaveModelData(worktimeId);
            }

            //Standard Arbeitzeit Eintrag anlegen mit Artbeitszeit und Pause.
            if (SubmitType == WorktimeHelper.BtnCreateDefaultEntryWithPause)
            {
                //Evtl. Modeldaten zurücksetzten und nur das aktuelle Datum übernehmen
                InitializeModelData(CurrentDate);
                //Die standardarbeitszeit übernehmen
                SaveModelData(worktimeId);

                //Die Daten wieder zurücksetzten und dann die Standardwerte für die Pause laden und speichern
                SaveDefaultBreaktimeData(worktimeId);
            }

            //Standard Pausenzeiteintrag für den aktuellen Tag anlegen
            if (SubmitType == WorktimeHelper.BtnCreateDefaultBreaktime)
            {
                SaveDefaultBreaktimeData(worktimeId);
            }

            //Standard Arbeitszeiteintrag anlegen OHNE Pause.
            if (SubmitType == WorktimeHelper.BtnCreateDefaultWorktime)
            {
                //Evtl. Modeldaten zurücksetzten und nur das aktuelle Datum übernehmen
                InitializeModelData(CurrentDate);
                //Die standardarbeitszeit übernehmen und speichern
                SaveModelData(worktimeId);
            }

            //Das Datum welches ausgewählt wurde laden
            if (SubmitType == WorktimeHelper.BtnLoadDate || SubmitType == WorktimeHelper.BtnResetData)
            {
                InitializeModelData(CurrentDate);
            }

            //Einen Tag vorspringen
            if (Controller.HttpContext.Request.Form.AllKeys.Contains(WorktimeHelper.BtnIdNextDay))
            {
                //genau berechnen anhand der Arbeitstagé des Users was der nächste Tag ist
                InitializeModelData(WorktimeSettings.GetNextWorkingDay(CurrentDate));
            }

            //Einen Tag zurückspringen
            if (Controller.HttpContext.Request.Form.AllKeys.Contains(WorktimeHelper.BtnIdPrevDay))
            {
                InitializeModelData(WorktimeSettings.GetPrevWorkingDay(CurrentDate));
            }

            //Laden von Standarddaten
            LoadDefaultData();
        }
        #endregion

        #region Private Functions
        /// <summary>
        /// Speichern der übergebenen Modeldaten in der DB für die übergebene worktimeId
        /// </summary>
        /// <param name="worktimeId">Die Arbeitszeit Id für die der Eintrag abgespeichert werden soll</param>
        /// <returns>TRUE->Speichern erfolgreich | FALSE->Fehler beim Speichern</returns>
        private void SaveModelData(long worktimeId)
        {
            WorktimeRepository repository = new WorktimeRepository(CurrentHttpContext.GetDataModel());
            EFWorktimeEntry entry = new EFWorktimeEntry();
            EFWorktime worktime = null;
            //Wenn bereits eine WorktimeId übergeben wurde, dann den passenden Eintrag aus der DB laden.
            if (worktimeId != 0)
            {
                //TODO zusätzlich noch einmal prüfen ob der User die Rechte hat den Eintrag anzuzeigen.
                entry = repository.GetWorktimeEntry(UserId, worktimeId);
                //Wenn der Eintrag nicht gefunden werden kann, dann die passende Nachricht anzeigen.
                if (entry == null)
                {
                    CustomMessage.CurrentMessage(Controller).AddMessage(SystemMessages.WorkWorktimeEntryLoadSaveFailed, MessageTypes.error);
                    throw new Exception(SystemMessages.WorkWorktimeEntryLoadSaveFailed);
                }

                //Die passenden Arbeitszeiteintrag setzten.
                worktime = entry.EFWorktime;
            }
            else
            {
                //Sonst muss ein neuer Worktimeeintrag angelegt werden. Prüfen ob es für den Tag bereits einen Artbeitszeiteintrag gibt.
                worktime = repository.GetWorktime(UserId, CurrentDate.Date);
                if (worktime == null)
                {
                    //Wenn es noch keinen Arbeitszeiteintrag gibt, muss der Usergeladen werden für den der Eintrag angelegt werden soll
                    UserRepository userRepository = new UserRepository(CurrentHttpContext.GetDataModel());
                    EFAuthentication user = userRepository.GetUser(UserId);
                    if (user != null)
                    {
                        //Dem User den neuen Arbeitstag hinzufügen.
                        worktime = new EFWorktime();
                        worktime.EntryDate = CurrentDate.Date;
                        //Die Tage die gearbeitet werden soll für diesen Zeitraum, als Bitmix abspeichern, damit wir später wissen 
                        //wenn der Zeitraum geändert wurde, wann man früher Arbeitszeiten eintragen musste.
                        worktime.WorktimeDays = (int)TimeFunctions.WorkingDays(WorktimeSettings);
                        user.EFWorktime.Add(worktime);
                        //Dann dem Arbeitszeiteintrag dem Arbeitstag hinzufügen.
                        worktime.EFWorktimeEntry.Add(entry);
                    }
                    else
                    {
                        //TODO Fehlermeldung ausgeben, das der user nicht existiert
                        throw new Exception();
                    }
                }
            }

            //Arbeitszeitdaten entsprechend setzten
            entry.Module = EFModules.Worktime;
            entry.CreationDate = DateTime.Now;
            entry.EditDate = DateTime.Now;
            entry.CreatorID = CurrentSession.GetCurrentUser().ID;
            entry.EditorID = CurrentSession.GetCurrentUser().ID;
            entry.StartTime = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, StartTime.Hour, StartTime.Minute, 0);
            entry.EndTime = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, EndTime.Hour, EndTime.Minute, 0);
            entry.TimeInMinutes = TimeFunctions.DurationInMinutes(entry.StartTime, entry.EndTime);
            entry.Description = Description ?? string.Empty;
            entry.Notice = Notice ?? string.Empty;
            entry.WorkingtimeType = (EWorktimeType)int.Parse(WorktimeType);
            repository.SaveWorktimeEntry(entry, worktime);

            entry.EFWorktime.EFAuthenticationID = UserId;
            entry.EFWorktime.ManualOvertime = IsManualOvertime ? OvertimeInMinutes : 0;
            entry.EFWorktime.Overtime = IsManualOvertime ? 0 : OvertimeInMinutes;
            entry.EFWorktime.IsLegalHoliday = (EWorktimeType)int.Parse(WorktimeType) == EWorktimeType.OfficalHoliday;

            //Nur beim Projekttyp auch das passende Projekt zuordnen.
            if (entry.WorkingtimeType == EWorktimeType.Projecttime)
            {
                if (SelectedProject > 0)
                {
                    //WorktimeSettingsRepository settingsRepository = new WorktimeSettingsRepository(CurrentHttpContext.GetDataModel());
                    entry.EFWorktimeProjectId = SelectedProject;
                }
            }

            //Für unser Worktimeobjekt ermitteln welche Zeiten eingetragen werden müssen
            TimeManagement.TimeManagement.Management(entry.EFWorktime, CurrentHttpContext.GetDataModel()).SetTimesForWorktime(entry);

            //Den Eintrag der DB hinzufügen
            if (repository.SaveWorktimeEntry(entry, null))
            {
                //Wenn das Speichern der Daten erfolgreich war, dann müssen die Modeldaten "zurückgesetzt werden, damit ein neuer Eintrag angelegt werden kann
                InitializeModelData(CurrentDate);
                CustomMessage.CurrentMessage(Controller).AddMessage(SystemMessages.WorktimeEntrySavedSuccessfull, MessageTypes.ok);
            }
            else
            {
                CustomMessage.CurrentMessage(Controller).AddMessage(SystemMessages.WorkWorktimeEntrySaveFailed, MessageTypes.error);
            }
        }

        /// <summary>
        /// Die passenden Daten für die Arbeitszeitliste laden. Hier gibt es unterschiedliche Varianten. zum einen nur die Einträge des aktuellen Tages laden und 
        /// dann z.b. noch die letzten xx Einträge laden.
        /// </summary>
        private void InitializeWorktimeList()
        {
            //Der Listentyp der angezeigt wird, wird vom aktuellen User geladen und nicht von dem User der angezeigt wird
            //Damit man z.b. nicht die anzeige eines anderen Users ändern kann.
            WorktimeListType = CurrentSession.GetCurrentUser().EFWorktimeSetting.WorktimeListType;

            //Die Listen zurücksetzten bzw. initialisieren
            WorktimeList = new List<ListEntry>();
            WorktimeListDiagramm = new List<ListEntry>();

            WorktimeRepository worktimeRepository = new WorktimeRepository(CurrentHttpContext.GetDataModel());
            IQueryable<EFWorktimeEntry> worktimeEntries = new EnumerableQuery<EFWorktimeEntry>(new List<EFWorktimeEntry>());

            //Prüfen welcher Listentyp angezeigt werden soll und dann die passende Abfrage ausführen
            switch (WorktimeListType)
            {
                case EWorktimeListTypes.ByDay:
                    worktimeEntries = worktimeRepository.GetWorktimeEntriesByDay(UserId, CurrentDate);
                    break;

                case EWorktimeListTypes.ByEntries:
                    worktimeEntries = worktimeRepository.GetLastWorktimeEntries(UserId, 10);
                    break;
            }

            //Alle Abfragewerte aus dem EfModel in unser Datenmodel überführen.
            foreach (EFWorktimeEntry entry in worktimeEntries)
            {
                //Prüfen um welchen Eingabetyp es sich handelt und dann passend die jeweilige Dauer setzten
                int duration = 0;
                switch (entry.WorkingtimeType)
                {
                    case EWorktimeType.Holiday:
                        duration = entry.EFWorktime.Holidaytime;
                        break;
                    case EWorktimeType.Illness:
                        duration = entry.EFWorktime.Illness;
                        break;
                    case EWorktimeType.Breaktime:
                        duration = entry.EFWorktime.Breaktime;
                        break;
                    case EWorktimeType.Projecttime:
                        duration = entry.EFWorktime.Projecttime;
                        break;
                    case EWorktimeType.Qualification:
                        duration = entry.EFWorktime.Qualificationtime;
                        break;
                    case EWorktimeType.Worktime:
                        duration = entry.EFWorktime.Worktime;
                        break;
                    //Offizielle Feiertag wird nicht benötigt, da hier keine Zeiten berechnet werden.
                }

                //Neuen Eintrag anlegen
                WorktimeList.Add(new ListEntry()
                                     {
                                         CurrentDate = entry.Date,
                                         StartTime = entry.StartTime,
                                         EndTime = entry.EndTime,
                                         Description = entry.Description,
                                         Notice = entry.Notice,
                                         IsManualOverTime = entry.EFWorktime.ManualOvertime > 0,
                                         ManualOvertimeInMinutes = entry.EFWorktime.ManualOvertime,
                                         WorktimeType = entry.WorkingtimeType,
                                         WorktimeId = entry.ID,
                                         UserId = entry.EFWorktime.EFAuthenticationID,
                                         HasProject = entry.EFWorktimeProjectId.HasValue,
                                         ProjectName = entry.EFWorktimeProjectId.HasValue ? entry.EFWorktimeProject.Name : string.Empty,
                                         Duration = duration
                                     });
            }

            //Wir müssen die Liste für den aktuellen Tag für das Anzeigediragramm auch entsprechend mit Daten füllen.
            if (WorktimeListType == EWorktimeListTypes.ByDay)
            {
                WorktimeListDiagramm = WorktimeList;
            }
            else
            {
                //Sonder extra abfragen, damit wir auch die Liste für den aktuellen Tag erhalten
                foreach (EFWorktimeEntry entry in worktimeRepository.GetWorktimeEntriesByDay(UserId, CurrentDate))
                {
                    //Neuen Eintrag anlegen, hier sind aber nicht alle Angaben notwendig.
                    WorktimeListDiagramm.Add(new ListEntry()
                    {
                        CurrentDate = entry.Date,
                        StartTime = entry.StartTime,
                        EndTime = entry.EndTime,
                        WorktimeType = entry.WorkingtimeType,
                    });
                }
            }
        }

        /// <summary>
        /// Initialisieren der Modeldaten, wird z.b. beim Anlegen eines Neuen Arbeitszeit Eintrags benötigt.
        /// </summary>
        private void InitializeModelData(DateTime currentDate)
        {
            //TODO evtl. prüfen ob für den Tag bereits ein Arbeitszeit eintrag besteht und dann direkt einen Pauseneintrag vorschlagen
            //Wenn ein Pauseneintrag bereits existiert, dann einen Projekteintrag vorschlagen.

            //Initialisieren der Modeldaten
            WorktimeId = 0;
            CurrentDate = currentDate;
            StartTime = WorktimeSettings.DefaultStartWorkingTime;
            EndTime = WorktimeSettings.DefaultEndWorkingTime;
            Description = WorktimeSettings.DefaultWorktimeDescription;
            OvertimeInMinutes = 0;
            Notice = string.Empty;
            WorktimeType = ((int)EWorktimeType.Worktime).ToString();
            SelectedProject = -1;
            IsManualOvertime = false;
            WorktimeListType = CurrentSession.GetCurrentUser().EFWorktimeSetting.WorktimeListType;
        }

        /// <summary>
        /// Den Standarfpausenzeiteintrag anlegen
        /// </summary>
        /// <param name="worktimeId"></param>
        private void SaveDefaultBreaktimeData(long worktimeId)
        {
            //Die Daten wieder zurücksetzten und dann die Standardwerte für die Pause laden und speichern
            InitializeModelData(CurrentDate);
            StartTime = WorktimeSettings.DefaultStartBreakTime;
            EndTime = WorktimeSettings.DefaultEndBreakTime;
            Description = string.Empty;
            WorktimeType = ((int)EWorktimeType.Breaktime).ToString();
            SaveModelData(worktimeId);
        }
        #endregion
    }
}